home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / dtime / data.1 / WIN32SUP.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-08  |  18.8 KB  |  590 lines

  1. /*
  2. Module : win32sup.cpp
  3. Purpose: Defines a number of components to allow dtime code to be portable across
  4.          Win32n(NT), Win32c(95), Win32s, Win16 & Dos
  5. Created: PJN / DATE/2 / 29-04-1996
  6. History: None
  7.  
  8. Copyright (c) 1996 by PJ Naughter.  
  9. All rights reserved.
  10.  
  11. */
  12.  
  13. /////////////////////////////////  Includes  //////////////////////////////////
  14. #include "stdafx.h"
  15. #include "resource.h"
  16. #include <stdarg.h>
  17. #include <ctype.h>
  18. #include "win32sup.h"
  19. #include "datetime.h"
  20.  
  21.  
  22. /////////////////////////////// Local Functions ///////////////////////////////
  23. #ifdef _DOS
  24. void AfxFormatStrings(CString& rString, UINT nIDS, const char* rglpsz, int nString);
  25. void AfxFormatStrings(CString& rString, const char* pszFormat, const char* rglpsz, int nString);
  26. #endif
  27.  
  28.  
  29.  
  30. /////////////////////////////////  Macros  ////////////////////////////////////
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36.  
  37.  
  38. /////////////////////////////// Implementation ////////////////////////////////
  39.  
  40. char* MyGetEnv(const char* pszVariableName)
  41. {                  
  42.   #if defined(_WINDOWS) && !defined(_WIN32) && defined(_AFXDLL) //call our own version of getenv
  43.     return DLLGetEnv(pszVariableName);    //if in a Win16 dll
  44.   #else
  45.     return getenv(pszVariableName);
  46.   #endif
  47. }
  48.  
  49.  
  50.  
  51. #ifndef _WIN32
  52.  
  53.  
  54. #ifdef _WINDOWS      
  55. //The reason the DllGetEnv function is required instead is because of a limitation of getenv
  56. //in Win16 DLL's. See the article Q78542 on the MSDN for a full explanation
  57. char* DLLGetEnv(const char* pszVariableName)
  58. {
  59.   char* pEnvSearch; 
  60.   const char* pszVarSearch;
  61.                             
  62.   //Check for a NULL pointer                          
  63.   if (!*pszVariableName )  
  64.     return NULL;
  65.  
  66.   //  Get a pointer to the MS-DOS environment block
  67.   pEnvSearch = GetDOSEnvironment();
  68.  
  69.   while ( *pEnvSearch )  //While there are strings to parse
  70.   {     
  71.     /*
  72.     Make a copy of the pointer to the name of the
  73.     environment variable to search for.
  74.     */
  75.     pszVarSearch = pszVariableName;
  76.  
  77.     //  Check to see if the variable names match
  78.     while (*pEnvSearch && *pszVarSearch &&
  79.            *pEnvSearch == *pszVarSearch )
  80.     {
  81.       pEnvSearch++;
  82.       pszVarSearch++;
  83.     }
  84.  
  85.     /*
  86.     If the names match, the lpEnvSearch pointer is on the "="
  87.     character and lpszVarSearch is on a null terminator.
  88.     Increment and return lpszEnvSearch, which will point to the
  89.     environment variable's contents.
  90.     
  91.     If the names do not match, increment lpEnvSearch until it
  92.     reaches the end of the current variable string.
  93.     */
  94.     if (*pEnvSearch == '=' && *pszVarSearch == '\0')
  95.       return (pEnvSearch + 1);
  96.     else
  97.       while (*pEnvSearch)
  98.         pEnvSearch++;
  99.  
  100.     /*
  101.     At this point the end of the environment variable's string
  102.     has been reached. Increment lpEnvSearch to move to the
  103.     next variable in the environment block. If it is NULL,
  104.     the end of the environment block has been reached.
  105.     */
  106.     pEnvSearch++;
  107.   }
  108.  
  109.   /*
  110.   If this section of code is reached, the variable
  111.   was not found.
  112.   */
  113.   return NULL;
  114. }
  115. #endif //_WINDOWS
  116.   
  117.  
  118.   
  119.  
  120. DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
  121. {             
  122.   //Ini files could have been used on Win32s, Win16 but then another
  123.   //method would be required for Dos as the Get/Write Profile.. are Windows
  124.   //specific, hence the reason environment variables are used. This will
  125.   //also allow DTime to ported to UNIX more easily in the furture.     
  126.   DWORD rVal;
  127.   
  128.   //default to some reasonable values
  129.   lpTimeZoneInformation->StandardDate.wYear = 0;  
  130.   lpTimeZoneInformation->StandardDate.wMonth = 10;  
  131.   lpTimeZoneInformation->StandardDate.wDayOfWeek = 0;        
  132.   lpTimeZoneInformation->StandardDate.wDay = 5;  
  133.   lpTimeZoneInformation->StandardDate.wHour = 2;  
  134.   lpTimeZoneInformation->StandardDate.wMinute = 0;  
  135.   lpTimeZoneInformation->StandardDate.wSecond = 0;
  136.   lpTimeZoneInformation->StandardDate.wMilliseconds = 0;
  137.     
  138.   lpTimeZoneInformation->DaylightDate.wYear = 0;  
  139.   lpTimeZoneInformation->DaylightDate.wMonth = 3;  
  140.   lpTimeZoneInformation->DaylightDate.wDayOfWeek = 0;        
  141.   lpTimeZoneInformation->DaylightDate.wDay = 5;  
  142.   lpTimeZoneInformation->DaylightDate.wHour = 1;  
  143.   lpTimeZoneInformation->DaylightDate.wMinute = 0;  
  144.   lpTimeZoneInformation->DaylightDate.wSecond = 0;     
  145.   lpTimeZoneInformation->DaylightDate.wMilliseconds = 0;
  146.  
  147.   
  148.   //Any values which can be taken from the standard TZ environment value
  149.   
  150.   if (MyGetEnv("TZ"))
  151.   {                                 
  152.     _tzset();                                                   
  153.     _fstrcpy(lpTimeZoneInformation->StandardName, _tzname[0]);
  154.     _fstrcpy(lpTimeZoneInformation->DaylightName, _tzname[1]);
  155.         
  156.     if (_daylight)
  157.     { 
  158.       lpTimeZoneInformation->DaylightBias = -60;
  159.       rVal = TIME_ZONE_ID_DAYLIGHT;      
  160.     }  
  161.     else
  162.     {
  163.       lpTimeZoneInformation->DaylightBias = 0;
  164.       rVal = TIME_ZONE_ID_STANDARD;
  165.     }  
  166.     lpTimeZoneInformation->StandardBias = 0;
  167.     lpTimeZoneInformation->Bias = _timezone/60;
  168.   }
  169.   else  //if no TZ environment is set then assume UCT timeframe and no daylight settings
  170.         //This behaviour is different to the 16 bit c runtime library which defaults
  171.         //to "PST8PDT"
  172.   {
  173.     _fstrcpy(lpTimeZoneInformation->StandardName, "");
  174.     _fstrcpy(lpTimeZoneInformation->DaylightName, "");
  175.     lpTimeZoneInformation->DaylightBias = -60;
  176.     lpTimeZoneInformation->StandardBias = 0;
  177.     lpTimeZoneInformation->Bias = 0;
  178.     rVal = TIME_ZONE_ID_STANDARD;    
  179.   }
  180.   
  181.   //the rest of the values required in TIME_ZONE_INFORMATION
  182.   //are taken from environment variables newly defined for DTIME
  183.   char* pszEnvVar = MyGetEnv("STD_DATE");
  184.   if (pszEnvVar)
  185.   {                
  186.     //take a copy of the string so that any changes
  187.     //we make will not be reflected back into the environment
  188.     char* pszStandardDate = new char[strlen(pszEnvVar)];
  189.     
  190.     if (pszStandardDate)
  191.     {
  192.       strcpy(pszStandardDate, pszEnvVar);
  193.     
  194.       BOOL bParseOK = TRUE;
  195.       char* sepChars = " ";
  196.                 
  197.       char* pszTok = strtok(pszStandardDate, sepChars);
  198.       bParseOK = (pszTok != NULL); 
  199.       
  200.       if (bParseOK)        
  201.         lpTimeZoneInformation->StandardDate.wYear = (WORD) atoi(pszTok);
  202.         
  203.       pszTok = strtok(NULL, sepChars); 
  204.       bParseOK = bParseOK && (pszTok != NULL);         
  205.       if (bParseOK)
  206.         lpTimeZoneInformation->StandardDate.wMonth = (WORD) atoi(pszTok);   
  207.   
  208.       pszTok = strtok(NULL, sepChars);             
  209.       bParseOK = bParseOK && (pszTok != NULL);               
  210.       if (bParseOK)
  211.         lpTimeZoneInformation->StandardDate.wDayOfWeek = (WORD) atoi(pszTok);
  212.   
  213.       pszTok = strtok(NULL, sepChars);             
  214.       bParseOK = bParseOK && (pszTok != NULL);               
  215.       if (bParseOK)
  216.         lpTimeZoneInformation->StandardDate.wDay = (WORD) atoi(pszTok);
  217.   
  218.       pszTok = strtok(NULL, sepChars); 
  219.       bParseOK = bParseOK && (pszTok != NULL);         
  220.       if (bParseOK)
  221.         lpTimeZoneInformation->StandardDate.wHour = (WORD) atoi(pszTok);   
  222.   
  223.       pszTok = strtok(NULL, sepChars);             
  224.       bParseOK = bParseOK && (pszTok != NULL);   
  225.       if (bParseOK)            
  226.         lpTimeZoneInformation->StandardDate.wMinute = (WORD) atoi(pszTok);
  227.   
  228.       pszTok = strtok(NULL, sepChars);             
  229.       bParseOK = bParseOK && (pszTok != NULL);               
  230.       if (bParseOK)
  231.         lpTimeZoneInformation->StandardDate.wSecond = (WORD) atoi(pszTok); 
  232.         
  233.       delete []pszStandardDate;  
  234.     }  
  235.   }                                                              
  236.  
  237.  
  238.   pszEnvVar = MyGetEnv("DYLT_DATE");
  239.   if (pszEnvVar)
  240.   { 
  241.     //take a copy of the string so that any changes
  242.     //we make will not be reflected back into the environment
  243.     char* pszDaylightDate = new char[strlen(pszEnvVar)];
  244.     
  245.     if (pszDaylightDate)
  246.     {
  247.       strcpy(pszDaylightDate, pszEnvVar);
  248.   
  249.       BOOL bParseOK = TRUE; 
  250.       char* sepChars = " ";
  251.                 
  252.       char* pszTok = strtok(pszDaylightDate, sepChars);
  253.       bParseOK = (pszTok != NULL);         
  254.       if (bParseOK)    
  255.         lpTimeZoneInformation->DaylightDate.wYear = (WORD) atoi(pszTok);
  256.               
  257.       pszTok = strtok(NULL, sepChars); 
  258.       bParseOK = bParseOK && (pszTok != NULL);         
  259.       if (bParseOK)    
  260.         lpTimeZoneInformation->DaylightDate.wMonth = (WORD) atoi(pszTok);   
  261.       
  262.       pszTok = strtok(NULL, sepChars);             
  263.       bParseOK = bParseOK && (pszTok != NULL);               
  264.       if (bParseOK)    
  265.         lpTimeZoneInformation->DaylightDate.wDayOfWeek = (WORD) atoi(pszTok);
  266.           
  267.       pszTok = strtok(NULL, sepChars);
  268.       bParseOK = bParseOK && (pszTok != NULL);               
  269.       if (bParseOK)    
  270.         lpTimeZoneInformation->DaylightDate.wDay = (WORD) atoi(pszTok);
  271.   
  272.       pszTok = strtok(NULL, sepChars); 
  273.       bParseOK = bParseOK && (pszTok != NULL);         
  274.       if (bParseOK)    
  275.         lpTimeZoneInformation->DaylightDate.wHour = (WORD) atoi(pszTok);   
  276.   
  277.       pszTok = strtok(NULL, sepChars);             
  278.       bParseOK = bParseOK && (pszTok != NULL);               
  279.       if (bParseOK)    
  280.         lpTimeZoneInformation->DaylightDate.wMinute = (WORD) atoi(pszTok);
  281.   
  282.       pszTok = strtok(NULL, sepChars);             
  283.       bParseOK = bParseOK && (pszTok != NULL);               
  284.       if (bParseOK)    
  285.         lpTimeZoneInformation->DaylightDate.wSecond = (WORD) atoi(pszTok);
  286.   
  287.       delete []pszDaylightDate;                                  
  288.     }  
  289.   }                                                              
  290.   
  291.   
  292.   return rVal;
  293. }
  294.  
  295.  
  296.                 
  297. #ifdef _WINDOWS
  298.  
  299. int Win16Printf(const char *format, ...)
  300. {   
  301.   CString sOut;
  302.   va_list argList;
  303.   va_start(argList, format);
  304.   sOut.FormatV(format, argList);
  305.   va_end(argList);
  306.   OutputDebugString(sOut);
  307.   return sOut.GetLength();
  308. }
  309.  
  310. #endif //_WINDOWS               
  311.                
  312.  
  313. //to avoid circular calls                           
  314.  
  315. #undef CString
  316.  
  317.  
  318. CStringEx::CStringEx()
  319. {          
  320. }
  321.                                     
  322.  
  323. CStringEx::CStringEx(const CString& stringSrc) : CString(stringSrc)
  324. {
  325. }
  326.  
  327.  
  328. CStringEx::CStringEx(char ch, int nRepeat) : CString(ch, nRepeat)
  329. {       
  330. }
  331.  
  332.  
  333. CStringEx::CStringEx(const char* psz) : CString(psz)
  334. }
  335.  
  336.  
  337. CStringEx::CStringEx(const char* pch, int nLength) : CString(pch, nLength)
  338.  
  339.  
  340.  
  341. void CStringEx::FormatV(const char* pszFormat, va_list argList)
  342. {   
  343.   ASSERT(AfxIsValidString(pszFormat));
  344.  
  345.   GetBuffer(512);
  346.   VERIFY(vsprintf(m_pchData, pszFormat, argList) <= GetAllocLength());
  347.   ReleaseBuffer();
  348.   va_end(argList);
  349. }
  350.  
  351.  
  352. void CStringEx::Format(const char* pszFormat, ...)
  353. {
  354.   ASSERT(AfxIsValidString(pszFormat));
  355.  
  356.   va_list argList;
  357.   va_start(argList, pszFormat);
  358.   FormatV(pszFormat, argList);
  359.   va_end(argList);
  360.  
  361.  
  362. void CStringEx::Format(UINT nFormatID, ...)
  363. {
  364.   CStringEx strFormat;
  365.   VERIFY(strFormat.LoadString(nFormatID) != 0);
  366.  
  367.   va_list argList;
  368.   va_start(argList, nFormatID);
  369.   FormatV(strFormat, argList);
  370.   va_end(argList);
  371. }
  372.  
  373.  
  374. //back to override                                                    
  375. #define CString CStringEx
  376.  
  377.  
  378.  
  379. #endif //_WIN32
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386. #ifdef _DOS
  387. void AfxFormatStrings(CStringEx& rString, UINT nIDS, const char* rglpsz, int nString)
  388. {
  389.   CStringEx sText;
  390.   ASSERT(sText.LoadString(nIDS));
  391.   AfxFormatStrings(rString, sText, rglpsz, nString);
  392. }
  393.    
  394.  
  395. void AfxFormatStrings(CStringEx& rString, const char* pszFormat, const char* rglpsz, int nString)
  396. {
  397.   // NOTE: will not work for strings > 255 characters
  398.   
  399.   int nTotalLen = lstrlen(pszFormat);
  400.   for (int i = 0; i < nString; i++)
  401.   {
  402.     if (rglpsz[i] != NULL)
  403.       nTotalLen += strlen(&rglpsz[i]);
  404.   }
  405.  
  406.   const char* pchSrc = pszFormat;
  407.   char* pchDest = rString.GetBuffer(nTotalLen+1);
  408.   while (*pchSrc != '\0')
  409.   {
  410.     if (pchSrc[0] == '%' && (pchSrc[1] >= '1' && pchSrc[1] <= '9'))
  411.     {
  412.       i = pchSrc[1] - '1';
  413.       pchSrc += 2;
  414.       if (i >= nString)
  415.       {
  416.         TRACE1("Error: illegal string index requested %d\n", i);
  417.         *pchDest++ = '?';
  418.       }
  419.       else if (rglpsz[i] != NULL)
  420.       {
  421.         strcpy(pchDest, &rglpsz[i]);
  422.         pchDest += strlen(pchDest);
  423.       }
  424.     }
  425.     else
  426.     {
  427.       if (_AfxIsDBCSLeadByte(*pchSrc))
  428.         *pchDest++ = *pchSrc++; // copy first of 2 bytes
  429.       *pchDest++ = *pchSrc++;
  430.     }
  431.   }
  432.   rString.ReleaseBuffer((int)((const char*)pchDest - (const char*)rString));
  433.   // Release will assert if we went too far
  434. }
  435.  
  436.  
  437. void AfxFormatString1(CStringEx& rString, UINT nIDS, const char* psz1)
  438. {                                                               
  439.   AfxFormatStrings(rString, nIDS, psz1, 1);
  440. }
  441.                                  
  442.                                  
  443.                                  
  444.                                  
  445.                                  
  446.                                  
  447.   
  448. //////////////// Implementation of CString::LoadString for Dos ////////////////
  449.  
  450. typedef struct _STRING_RES
  451.   unsigned int nID;
  452.   char* sText;
  453. } STRING_RES;
  454.  
  455.  
  456. //actual string table used by DTime, this should be kept in sync with
  457. //the rc file that DTime uses on Win16/Win32
  458.  
  459. STRING_RES StringTable[] =
  460. {                             
  461.   {  IDS_WEEKDAY1,            "Sunday"},
  462.   {  IDS_WEEKDAY2,            "Monday"},
  463.   {  IDS_WEEKDAY3,            "Tuesday"},
  464.   {  IDS_WEEKDAY4,            "Wednesday"},
  465.   {  IDS_WEEKDAY5,            "Thursday"},
  466.   {  IDS_WEEKDAY6,            "Friday"},
  467.   {  IDS_WEEKDAY7,            "Saturday"},
  468.   {  IDS_ABR_WEEKDAY1,        "Sun"},
  469.   {  IDS_ABR_WEEKDAY2,        "Mon"},
  470.   {  IDS_ABR_WEEKDAY3,        "Tue"},
  471.   {  IDS_ABR_WEEKDAY4,        "Wed"},
  472.   {  IDS_ABR_WEEKDAY5,        "Thur"},
  473.   {  IDS_ABR_WEEKDAY6,        "Fri"},
  474.   {  IDS_ABR_WEEKDAY7,        "Sat"},
  475.   {  IDS_MONTH1,              "January"},
  476.   {  IDS_MONTH2,              "February"},
  477.   {  IDS_MONTH3,              "March"},
  478.   {  IDS_MONTH4,              "April"},
  479.   {  IDS_MONTH5,              "May"},
  480.   {  IDS_MONTH6,              "June"},
  481.   {  IDS_MONTH7,              "July"},
  482.   {  IDS_MONTH8,              "August"},
  483.   {  IDS_MONTH9,              "September"},
  484.   {  IDS_MONTH10,             "October"},
  485.   {  IDS_MONTH11,             "November"},
  486.   {  IDS_MONTH12,             "December"},
  487.   {  IDS_ABR_MONTH1,          "Jan"},
  488.   {  IDS_ABR_MONTH2,          "Feb"},
  489.   {  IDS_ABR_MONTH3,          "Mar"},
  490.   {  IDS_ABR_MONTH4,          "Apr"},
  491.   {  IDS_ABR_MONTH5,          "May"},
  492.   {  IDS_ABR_MONTH6,          "Jun"},
  493.   {  IDS_ABR_MONTH7,          "Jul"},
  494.   {  IDS_ABR_MONTH8,          "Aug"},
  495.   {  IDS_ABR_MONTH9,          "Sep"},
  496.   {  IDS_ABR_MONTH10,         "Oct"},
  497.   {  IDS_ABR_MONTH11,         "Nov"},
  498.   {  IDS_ABR_MONTH12,         "Dec"},
  499.   {  IDS_INVALID_DATE_RANGE,  "The date entered is outside of the allowable range"},
  500.   {  IDS_INVALID_TIMESPAN_RANGE, 
  501.                             "The time span entered is outside of the allowable range"},
  502.   {  IDS_INVALID_TIMEOFDAY_RANGE, 
  503.                             "The time of day entered is outside of the allowable range"},
  504.   {  IDS_INVALID_DATE_MIN,    "The date entered is earlier that the allowable value"},
  505.   {  IDS_INVALID_TIMESPAN_MIN, 
  506.                             "The time span entered is earlier that the allowable value"},
  507.   {  IDS_INVALID_TIMEOFDAY_MIN, 
  508.                             "The time of day entered is earlier that the allowable value"},
  509.   {  IDS_INVALID_DATE_MAX,    "The date entered is later that the allowable value"},
  510.   {  IDS_INVALID_TIMESPAN_MAX, 
  511.                             "The time span entered is later that the allowable value"},
  512.   {  IDS_INVALID_TIMEOFDAY_MAX, 
  513.                             "The time of day entered is later that the allowable value"},
  514.   {  IDS_CEYEAR,              "%1 CE"},
  515.   {  IDS_BCEYEAR,             "%1 BCE"},
  516.   {  IDS_LOCAL,               "Local"},
  517.   {  IDS_UTC,                 "UTC"},
  518.   {  IDS_ET,                  "ET"},
  519.   {  IDS_AM,                  "AM"},
  520.   {  IDS_PM,                  "PM"},
  521.   {  IDS_INVALID_DATE,        "A valid date must be entered."},
  522.   {  IDS_INVALID_TIMESPAN,    "A valid time span must be entered."},
  523.   {  IDS_INVALID_TIMEOFDAY,   "A valid time of day must be entered."},
  524.   {  IDS_INVALID_LDATE,       "A valid long date must be entered."},
  525.   {  IDS_INVALID_LDATE_MIN,   "The long date entered is earlier that the allowable value"},
  526.   {  IDS_INVALID_LDATE_MAX,   "The long date entered is later that the allowable value"},
  527.   {  IDS_YEAR,                "Year"},
  528.   {  IDS_MONTH,               "Month"},
  529.   {  IDS_DAY,                 "Day"},
  530.   {  IDS_HOUR,                "Hour"},
  531.   {  IDS_MINUTE,              "Minute"},
  532.   {  IDS_SECOND,              "Second"},
  533.   {  IDS_MILLISECOND,         "Millisecond"},
  534.   {  IDS_ABR_HOUR,            "H"},
  535.   {  IDS_ABR_MINUTE,          "M"},
  536.   {  IDS_ABR_SECOND,          "S"},
  537.   {  IDS_ABR_MILLISECOND,     "MS"},
  538.   {  IDS_TIMEFRAME,           "Timeframe"},
  539.   {  IDS_ENTERED_INVALID_DATE, 
  540.                             "Please enter a valid date. A Possible reason that the date is invalid is that it occured during the skip when the Gregorian calendar was introduced."},
  541.   {  IDS_ENTERED_INVALID_LDATE, 
  542.                             "Please enter a valid long date. Possible reasons that the date is invalid is that it occured during the skip when the Gregorian calendar was introduced or when Daylight Savings was introduced or removed."},
  543.   {  IDS_EDIT_TEXT,           "..."},
  544.   {  IDS_UNICODE_DEBUG,       "(Unicode Debug Build)"},
  545.   {  IDS_UNICODE_RELEASE,     "(Unicode Release Build)"},
  546.   {  IDS_ASCII_DEBUG,         "(Ascii Debug Build)"},
  547.   {  IDS_ASCII_RELEASE,       "(Ascii Release Build)"},
  548.   {  IDS_SHAREWARE_CAPTION,   "DTime v%1 %2"},
  549.   {  IDS_TT_PUSHPIN,          "Keep Visible"},
  550.   {  IDS_TT_MODIFY,           "Modify"}
  551. };  
  552.  
  553.  
  554. //The function to the the actual load  
  555.                                    
  556.  
  557. BOOL CStringEx::LoadString(UINT nID)
  558. {                                
  559.   //this is not intended as a generic solution but just enough
  560.   //to make DTime work on Dos without too many changes.
  561.   //A generic solution would store the actual string table on
  562.   //file, would buffer access to it, and would use a binary search
  563.   //instead of our simple linear search
  564.   
  565.   int nNumEntries = sizeof(StringTable) / sizeof(STRING_RES);
  566.  
  567.   //simple linear search through the table, nothing fancy                                 
  568.   for (int i = 0; i<nNumEntries; i++)
  569.   {
  570.     if (StringTable[i].nID == nID)
  571.     {
  572.       *this = StringTable[i].sText;
  573.       return TRUE;
  574.     }
  575.   }
  576.   
  577.   return FALSE;
  578.  
  579.  
  580.  
  581. #endif // _DOS
  582.  
  583.  
  584.